package internal

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"rsync-code/common"
	"strings"

	"github.com/spf13/viper"
)

// CreateRepoRequest 结构体用于表示请求体中的数据
type CreateRepoRequest struct {
	Name    string `json:"name"`
	Private bool   `json:"private"`
}

// CreateRepo 创建 gitcode 项目
func CreateRepo(fullName string) bool {
	// 访问令牌
	accessToken := viper.GetString("gitcode_token")
	// 获取组织仓库与项目名
	org, repo := GetOwnerRepo([]string{fullName})

	// 生产环境处理项目映射
	if viper.GetBool("is_prod") {
		// 构建项目标识
		projectKey := fmt.Sprintf("%s/%s", org, repo)
		// 检查是否需要映射到其他组织
		for _, mapping := range viper.GetStringSlice("project_to_org") {
			parts := strings.Split(mapping, ":")
			if len(parts) == 2 && parts[0] == projectKey {
				org = parts[1]
				break
			}
		}
	} else {
		// 测试环境使用配置的组织名
		org = viper.GetString("gitcode_org")
	}
	// 构建请求 URL
	url := fmt.Sprintf("https://api.gitcode.com/api/v5/orgs/%s/repos?access_token=%s", org, accessToken)

	// 创建请求体
	requestBody := CreateRepoRequest{
		Name:    repo,
		Private: IsOwnerInPrivate(org),
	}

	// 将请求体编码为 JSON
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		common.Log.Errorf("JSON 编码失败: %v", err)
		return false
	}

	// 创建 HTTP POST 请求
	req, err := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
	if err != nil {
		common.Log.Errorf("创建请求失败: %v, URL: %s", err, url)
		return false
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")

	// 创建 HTTP 客户端
	client := &http.Client{}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		common.Log.Errorf("发送请求失败: %v\n", err)
		return false
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		common.Log.Errorf("读取响应体失败: %v\n", err)
		return false
	}

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnprocessableEntity {
		common.Log.Errorf("仓库创建失败,URL: %s 状态码: %d, 响应体: %s\n", url, resp.StatusCode, string(body))
		return false
	}
	return true
}

// SetPushConfig 设置项目的推送规则
func SetPushConfig(fullName string) bool {
	// 访问令牌
	accessToken := viper.GetString("gitcode_token")
	// 获取组织仓库与项目名
	owner, repo := GetOwnerRepo([]string{fullName})

	// 生产环境处理项目映射
	if viper.GetBool("is_prod") {
		// 构建项目标识
		projectKey := fmt.Sprintf("%s/%s", owner, repo)
		// 检查是否需要映射到其他组织
		for _, mapping := range viper.GetStringSlice("project_to_org") {
			parts := strings.Split(mapping, ":")
			if len(parts) == 2 && parts[0] == projectKey {
				owner = parts[1]
				break
			}
		}
	} else {
		// 测试环境使用配置的组织名
		owner = viper.GetString("gitcode_org")
	}

	// 构建请求 URL
	url := fmt.Sprintf("https://api.gitcode.com/api/v5/repos/%s/%s/push_config?access_token=%s", owner, repo, accessToken)

	// 创建请求体
	requestBody := map[string]interface{}{
		"max_file_size": viper.GetInt("max_file_size"),
	}

	// 将请求体编码为 JSON
	jsonData, err := json.Marshal(requestBody)
	if err != nil {
		common.Log.Errorf("JSON 编码失败: %v", err)
		return false
	}

	// 创建 HTTP PUT 请求
	req, err := http.NewRequest("PUT", url, bytes.NewBuffer(jsonData))
	if err != nil {
		common.Log.Errorf("创建请求失败: %v", err)
		return false
	}

	// 设置请求头
	req.Header.Set("Content-Type", "application/json")

	// 创建 HTTP 客户端
	client := &http.Client{}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		common.Log.Errorf("发送请求失败: %v", err)
		return false
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := io.ReadAll(resp.Body)
	if err != nil {
		common.Log.Errorf("读取响应体失败: %v", err)
		return false
	}

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK {
		common.Log.Errorf("设置推送规则失败, URL: %s 状态码: %d, 响应体: %s", url, resp.StatusCode, string(body))
		return false
	}

	common.Log.Infof("推送规则设置成功, URL: %s", url)
	return true
}
